//- interpreter:PythonInterpreterGetting.java
//Getting data from the PythonInterpreter object.
package v.book.read.tip.interpreter;

import org.python.util.PythonInterpreter;
import org.python.core.*;
import java.util.*;
import com.bruceeckel.python.*;
import junit.framework.*;

public class PythonInterpreterGetting extends TestCase {
	PythonInterpreter interp = new PythonInterpreter();

	public void test() throws PyException {
		interp.exec("a = 100");
		// If you just use the ordinary get(),
		// it returns a PyObject:
		PyObject a = interp.get("a");
		// There's not much you can do with a generic
		// PyObject, but you can print it out:
		System.out.println("a = " + a);
		// If you know the type it's supposed to be,
		// you can "cast" it using __tojava__() to
		// that Java type and manipulate it in Java.
		// To use 'a' as an int, you must use
		// the Integer wrapper class:
		int ai = ((Integer) a.__tojava__(Integer.class)).intValue();
		// There are also convenience functions:
		ai = Py.py2int(a);
		System.out.println("ai + 47 = " + (ai + 47));
		// You can convert it to different types:
		float af = Py.py2float(a);
		System.out.println("af + 47 = " + (af + 47));
		// If you try to cast it to an inappropriate
		// type you'll get a runtime exception:
		// ! String as = (String)a.__tojava__(
		// ! String.class);

		// If you know the type, a more useful method
		// is the overloaded get() that takes the
		// desired class as the 2nd argument:
		interp.exec("x = 1 + 2");
		int x = ((Integer) interp.get("x", Integer.class)).intValue();
		System.out.println("x = " + x);

		// Since Python is so good at manipulating
		// strings and files, you will often need to
		// extract an array of Strings. Here, a file
		// is read as a Python array:
		interp.exec("lines = " + "open('PythonInterpreterGetting.java')"
				+ ".readlines()");
		// Pull it in as a Java array of String:
		String[] lines = (String[]) interp.get("lines", String[].class);
		for (int i = 0; i < 10; i++)
			System.out.print(lines[i]);

		// As an example of useful string tools,
		// global expansion of ambiguous file names
		// using glob is very useful, but it's not
		// part of the standard Jython package, so
		// you'll have to make sure that your
		// Python path is set to include these, or
		// that you deliver the necessary Python
		// files with your application.
		interp.exec("from glob import glob");
		interp.exec("files = glob('*.java')");
		String[] files = (String[]) interp.get("files", String[].class);
		for (int i = 0; i < files.length; i++)
			System.out.println(files[i]);

		// You can extract tuples and arrays into
		// Java Lists with com.bruceeckel.PyUtil:
		interp.exec("tup = ('fee', 'fi', 'fo', 'fum', 'fi')");
		List tup = PyUtil.toList(interp, "tup");
		System.out.println(tup);
		// It really is a list of String objects:
		System.out.println(tup.get(0).getClass());
		// You can easily convert it to a Set:
		Set tups = new HashSet(tup);
		System.out.println(tups);
		interp.exec("ints=[1,3,5,7,9,11,13,17,19]");
		List ints = PyUtil.toList(interp, "ints");
		System.out.println(ints);
		// It really is a List of Integer objects:
		System.out.println((ints.get(1)).getClass());

		// If you have a Python dictionary, it can
		// be extracted into a Java Map, again with
		// com.bruceeckel.PyUtil:
		interp.exec("dict = { 1 : 'a', 3 : 'b',"
				+ "5 : 'c', 9 : 'd', 11 : 'e' }");
		Map map = PyUtil.toMap(interp, "dict");
		System.out.println("map: " + map);
		// It really is Java objects, not PyObjects:
		Iterator it = map.entrySet().iterator();
		Map.Entry e = (Map.Entry) it.next();
		System.out.println(e.getKey().getClass());
		System.out.println(e.getValue().getClass());
	}

	public static void main(String[] args) throws PyException {
		junit.textui.TestRunner.run(PythonInterpreterGetting.class);
	}
} // /:~